import React, {
  ReactElement,
  useContext,
  useEffect,
  useMemo,
  useState
} from 'react';
import { View, Image, Text, DeviceEventEmitter } from 'react-native';
import { RtcLocalView } from 'react-native-agora';

import styles from './style';
import { Store } from '../../reducer';
import { emptyScan, scan } from '../../../../constant/resource';
import { FacePositionChangeData } from '../../types';
import { lessonSign } from '../../actions';
import { phonePx } from '../../../../util/adapt';
import { getSignInTime, setSignInTime } from '../../store/sign';
import Button from '../../../../components/Button';
import { CLASS_ROOM_EVENT_FACE_POSITION_CHANGE } from '../../event';
import { isIOS, IS_SUPPORT_FACE_DETECTED } from '../../../../constant';
import { getNeedManualSignIn } from '../../../../store/gray';

const MAX_SIGN_IN_TIME = 3 * 1000;
let haveFace = !IS_SUPPORT_FACE_DETECTED;
let updateSignInTimer: NodeJS.Timer | null;
let facePositionChangeTimer: NodeJS.Timer | null;

const clearFacePositionChangeTimer = (): void => {
  if (facePositionChangeTimer) {
    clearTimeout(facePositionChangeTimer);
    facePositionChangeTimer = null;
  }
};

const clearSignInTimer = (): void => {
  if (updateSignInTimer) {
    clearInterval(updateSignInTimer);
    updateSignInTimer = null;
  }
};

export default (): ReactElement => {
  const [showVideo, setShowVideo] = useState(false);
  const [localHaveFace, setLocalHaveFace] = useState(!IS_SUPPORT_FACE_DETECTED);
  const [signTime, setSignTime] = useState(getSignInTime());

  const { state } = useContext(Store);
  const { showSignIn, isJoinedChannel, channel } = state;

  useEffect((): (() => void) => {
    if (!showSignIn) return (): void => {};
    const timer = setTimeout((): void => {
      setShowVideo(true);
    }, 500);

    return (): void => {
      if (timer) {
        clearTimeout(timer);
      }
    };
  }, [showSignIn]);

  useEffect((): (() => void) => {
    if (!showSignIn || !showVideo) return (): void => {};

    clearSignInTimer();
    updateSignInTimer = setInterval((): void => {
      setSignTime((time): number => {
        if (!haveFace) return time;

        const resTime = time + 100;
        if (resTime > MAX_SIGN_IN_TIME) {
          if (updateSignInTimer) {
            clearSignInTimer();
            lessonSign();
          }
          return time;
        }
        setSignInTime(resTime);
        return resTime;
      });
    }, 100);

    const subscription = DeviceEventEmitter.addListener(
      CLASS_ROOM_EVENT_FACE_POSITION_CHANGE,
      (data: FacePositionChangeData): void => {
        const { faceNumber } = data;
        haveFace = faceNumber > 0;
        setLocalHaveFace(haveFace);

        clearFacePositionChangeTimer();
        facePositionChangeTimer = setTimeout((): void => {
          haveFace = false;
          setLocalHaveFace(haveFace);
        }, 200);
      }
    );

    return (): void => {
      haveFace = false;
      setLocalHaveFace(haveFace);
      clearSignInTimer();
      clearFacePositionChangeTimer();
      if (subscription) {
        subscription.remove();
      }
    };
  }, [showSignIn, showVideo]);

  const needManualSignIn = getNeedManualSignIn();

  return useMemo((): ReactElement => {
    if (!showSignIn) return <View />;
    return (
      <View style={styles.container}>
        <Text style={styles.title}>完成签到 开始上课</Text>
        <View style={styles.area}>
          {isJoinedChannel && channel && showVideo && isIOS && (
            <RtcLocalView.SurfaceView
              style={styles.content}
              renderMode={1}
              channelId={channel}
              zOrderMediaOverlay
              // zOrderOnTop
            />
          )}
          {isJoinedChannel && channel && showVideo && !isIOS && (
            <RtcLocalView.TextureView
              style={styles.content}
              renderMode={1}
              channelId={channel}
            />
          )}
          <Image style={styles.content} source={showVideo ? emptyScan : scan} />
        </View>
        <View style={styles.timeContent}>
          <Text style={styles.desc}>请保持：</Text>
          <View style={styles.time}>
            <Text style={styles.timeValue}>0{Math.floor(signTime / 1000)}</Text>
          </View>
        </View>
        <View style={styles.processContent}>
          <View
            style={[
              styles.process,
              localHaveFace ? {} : styles.noFace,
              { width: (signTime / MAX_SIGN_IN_TIME) * phonePx(352) }
            ]}
          />
        </View>
        {needManualSignIn && (
          <Button
            style={styles.close}
            textStyle={styles.closeDesc}
            text="签到"
            onPress={(): void => {
              clearSignInTimer();
              lessonSign();
            }}
          />
        )}
      </View>
    );
  }, [
    channel,
    isJoinedChannel,
    localHaveFace,
    needManualSignIn,
    showSignIn,
    showVideo,
    signTime
  ]);
};
